package com.samebuilding.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.samebuilding.dao.DiaryDAO;
import com.samebuilding.domain.Diary;
import com.samebuilding.domain.User;

public class DiaryDAOImpl extends HibernateDaoSupport implements DiaryDAO {

	private static final String DELETE_BY_ID_AND_UID = "delete from Diary where id = ? and userNo = ?";
	private static final String FIND_BY_USERNO = "from Diary where userNo = ?";
	private static final String FIND_COUNT_BY_USER = "select count(*) from Diary where userNo = ?";
	
	private static final String FIND_BY_USERNO_IS_PUBLIC = "from Diary where userNo = ? and isPublic = 0";
	private static final String FIND_COUNT_BY_USER_IS_PUBLIC = "select count(*) from Diary where userNo = ? and isPublic = 0";
	
	public void deleteDiary(Diary d) {
		this.getHibernateTemplate().delete(d);
	}

	public void editDiary(Diary d) {
		this.getHibernateTemplate().update(d);
	}

	public Diary findById(int id) {
		List list= this.getHibernateTemplate().find("from Diary as d where d.id = ?",id);
		if(list!=null&&list.size()>0){
			return (Diary)list.get(0);
		}
		return null;
	}

	public List<Diary> findByUserNo(int userNo) {
		return this.getHibernateTemplate().find("from Diary as d where d.userNo = ?",userNo);
	}

	public void saveDiary(Diary d) {
		this.getHibernateTemplate().save(d);
	}

	public List<Diary> findByUserNoDWR(int userNo) {
		String hql = "from Diary as d where d.userNo = ? and d.isPublic = ?";
		Query query = this.getSession().createQuery(hql);
		query.setInteger(0, userNo);
		query.setInteger(1, 1);
		return query.list();
	}

	public void deleteDiary(final int id, final int userNo) {
		getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException,
					SQLException {
				Query query = s.createQuery(DELETE_BY_ID_AND_UID);
				query.setInteger(0, id);
				query.setInteger(1, userNo);
				query.executeUpdate();
				return null;
			}
		});
		
	}

	@SuppressWarnings("unchecked")
	public List<Diary> findByUserNo(final int userNo, final int start, final int limit) {
		return (List<Diary>)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_BY_USERNO);
				query.setInteger(0, userNo);
				query.setFirstResult(start);
				query.setMaxResults(limit);
				List<Diary> list = query.list();
				return list;
			}
		});
	}

	public int findCountByUserNo(final int userNo) {
		long count = (Long)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_COUNT_BY_USER);
				query.setInteger(0, userNo);

				return query.uniqueResult();
			}
		});
		return (int)count;
	}

	@SuppressWarnings("unchecked")
	public List<Diary> findByUserNoIsPublic(final int userNo, final int start, final int limit) {
		return (List<Diary>)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_BY_USERNO_IS_PUBLIC);
				query.setInteger(0, userNo);
				query.setFirstResult(start);
				query.setMaxResults(limit);
				List<Diary> list = query.list();
				return list;
			}
		});
	}

	public int findCountByUserNoIsPublic(final int userNo) {
		long count = (Long)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_COUNT_BY_USER_IS_PUBLIC);
				query.setInteger(0, userNo);

				return query.uniqueResult();
			}
		});
		return (int)count;
	}

}
